package pers.qianyu.diytomcat.servlets;

import cn.hutool.core.io.*;
import cn.hutool.core.util.*;
import pers.qianyu.diytomcat.catalina.*;
import pers.qianyu.diytomcat.classloader.*;
import pers.qianyu.diytomcat.constants.*;
import pers.qianyu.diytomcat.http.*;
import pers.qianyu.diytomcat.util.*;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;

/**
 * 处理 JSP 的 Servlet
 *
 * @author mizzle rain
 * @date 2021-01-13 11:52
 */
public class JspServlet extends HttpServlet {
    private JspServlet() {
    }

    private static final JspServlet INSTANCE = new JspServlet();

    public static JspServlet getInstance() {
        return INSTANCE;
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
        try {
            Request request = (Request) req;
            Response response = (Response) resp;

            String uri = request.getUri();
            String fileName;
            if (Objects.equals("/", uri)) {
                fileName = WebXmlUtil.getWelcomeFile(request.getContext());
            } else {
                fileName = StrUtil.subAfter(uri, "/", false);
            }

            File jspFile = FileUtil.file(request.getRealPath(fileName));
            if (jspFile.exists()) {
                Context context = request.getContext();
                String path = context.getPath();
                String subFolder;
                if (Objects.equals(path, "/")) {
                    subFolder = "_";
                } else {
                    subFolder = StrUtil.subAfter(path, "/", false);
                }
                uri = Objects.equals("/", uri) ? uri + fileName : uri;
                String servletPath = JspUtil.getServletClassPath(uri, subFolder);
                File jspServletFile = new File(servletPath);
                if (!jspServletFile.exists()) {
                    JspUtil.compileJsp(context, jspFile);
                } else if (jspFile.lastModified() > jspServletFile.lastModified()) {
                    JspUtil.compileJsp(context, jspFile);
                    JspClassLoader.invalidJspClassLoader(uri, context);
                }
                response.setContentType(WebXmlUtil.getMimeType(FileUtil.extName(jspFile)));

                JspClassLoader jspClassLoader = JspClassLoader.getJspClassLoader(uri, context);
                String jspServletClassName = JspUtil.getJspServletClassName(uri, subFolder);
                Class<?> jspServletClass = jspClassLoader.loadClass(jspServletClassName);
                HttpServlet servlet = context.getServlet(jspServletClass);
                servlet.service(request, response);
                if (Objects.isNull(response.getRedirectPath())) {
                    response.setStatus(HttpCode.CODE_200);
                } else {
                    response.setStatus(HttpCode.CODE_302);
                }
            } else {
                response.setStatus(HttpCode.CODE_404);
            }
        } catch (ClassNotFoundException | ServletException | IOException e) {
            e.printStackTrace();
        }

    }
}
